import java.util.Random;
import java.util.concurrent.TimeUnit;

public class ProducerConsumerTest {

	public static void main(String[] args) throws InterruptedException {
		ProducerConsumerPool pool = new ProducerConsumerPool();
		ProducerConsumerPool.Producer p1 = pool.new Producer(1000);
		ProducerConsumerPool.Consumer c1 = pool.new Consumer(1000);
		Thread t1 = new Thread(p1);
		Thread t2 = new Thread(c1);
		t1.start();
		t2.start();
		t1.join();
		t2.join();
		System.out.println(pool.getCount());
	}
}

class ProducerConsumerPool {
	private static final int CAPACITY = 10; // 代表仓库容量
	private int count = 0; // 代表仓库当前中的货物数量

	public synchronized int getCount() {
		return  count;
	}


	public synchronized void setCount(int i) {
		 count = i;
	}

	public synchronized void produce() throws InterruptedException { // 加synchronized同步
//		int temp = count;
//		try {
//			TimeUnit.NANOSECONDS.sleep(new Random().nextInt(5));
//		} catch (InterruptedException e) {
//			e.printStackTrace();
//		}
//		temp = temp + 1;
//		count = temp;
		while(count==CAPACITY) {
			wait();
		}
		count++;
		if (count > CAPACITY)
			throw new IllegalArgumentException("商品数量超过最大容量");
		notifyAll();
	}

	public synchronized void consume() throws InterruptedException { // 加synchronized同步
//		int temp = count;
//		try {
//			TimeUnit.NANOSECONDS.sleep(new Random().nextInt(5));
//		} catch (InterruptedException e) {
//			e.printStackTrace();
//		}
//		temp = temp - 1;
//		count = temp;
		while(count==0) {
			wait();
		}
		count--;
		if (count < 0)
			throw new IllegalArgumentException("仓库内商品数量为负数");
		notifyAll();
	}

	public class Producer implements Runnable {
		private int n; // 循环n次

		public Producer(int n) {
			this.n = n;
		}

		public void run() {
			for (int product = 0; product < n; product++) {
				try {
					produce();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}

			System.out.println(Thread.currentThread().getName() + " produed " + n + " now the count is " + count);
		}
	}

	public class Consumer implements Runnable {
		
		private int n; // 循环n次

		public Consumer(int n) {
			this.n = n;
		}

		public void run() {

			for (int i = 0; i < n; i++) {
				try {
					consume();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}			
			}

			System.out.println(Thread.currentThread().getName() + " consumed " + n + " now the count is " + count);
		}
	}
}
